import ContextPadProvider, { type ContextPadEntry } from "bpmn-js/lib/features/context-pad/ContextPadProvider";
import { type Element } from "bpmn-js/lib/model/Types";
import { type ContextPadTarget } from "diagram-js/lib/features/context-pad/ContextPad";
import translate from "diagram-js/lib/i18n/translate/translate";
import { assign } from "min-dash";

export default class CustomContextPad extends ContextPadProvider {

  /**
    * Create an append action.
    */
  appendAction<T extends Element>(type: string, className: string, title: string, options?: any): ContextPadEntry {

    // @ts-expect-error
    const autoPlace = this._autoPlace;
    // @ts-expect-error
    const create = this._create;
    // @ts-expect-error
    const elementFactory = this._elementFactory;

    if (typeof title !== 'string') {
      options = title;
      title = translate('Append {type}', { type: type.replace(/^bpmn:/, '') });
    }

    function appendStart(event: Event, element: ContextPadTarget<T>) {

      const shape = elementFactory.createShape(assign({ type }, options));
      create.start(event, shape, {
        source: element
      });
    }

    const append = autoPlace ? function (event: Event, element: ContextPadTarget<T>) {
      const shape = elementFactory.createShape(assign({ type }, options));

      autoPlace.append(element, shape);
    } : appendStart;

    return {
      group: 'model',
      className,
      title,
      action: {
        // @ts-expect-error bpmn-js类型落后实际
        dragstart: appendStart,
        click: append
      }
    };
  }

  getContextPadEntries(element: Element) {
    const result = super.getContextPadEntries(element);

    // console.log(result);
    delete result['append.intermediate-event']; // 隐藏中间事件
    if (result['append.append-task']) {
      // delete result['append.append-task'];
      // 只能走替换，否则位置会变换
      assign(result, {
        'append.append-task': this.appendAction(
          'bpmn:UserTask',
          'bpmn-icon-user-task',
          '添加用户任务'
        )
      });
    }
    return result;
  }
}
